package com.fendaren.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fendaren.base.BaseInfoProperties;
import com.fendaren.grace.result.GraceJSONResult;
import com.fendaren.grace.result.ResponseStatusEnum;
import com.fendaren.pojo.Users;
import com.fendaren.pojo.vo.SaasUserVO;
import com.fendaren.service.UsersService;
import com.fendaren.util.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.json.GsonJsonParser;
import org.springframework.http.converter.json.GsonBuilderUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("saas")
@Slf4j
public class SaasPassportController extends BaseInfoProperties {

    @Autowired
    private UsersService usersService;

    @Autowired
    private JWTUtils jwtUtils;

    @PostMapping("getQRToken")
    public GraceJSONResult getQRToken() {

        // 生成扫码登录的token
        String qrToken = UUID.randomUUID().toString();
        // 把qrToken存入到redis，设置一定时效，默认二维码超时
        redis.set(SAAS_PLATFORM_LOGIN_TOKEN + ":" + qrToken, qrToken, 5 * 60);
        // 存入redis标记当前的qrToken未被扫码读取
        redis.set(SAAS_PLATFORM_LOGIN_TOKEN_READ + ":" + qrToken, "0", 5 * 60);
        // 返回给前端
        return GraceJSONResult.ok(qrToken);
    }

    @PostMapping("scanCode")
    public GraceJSONResult scanCode(String qrToken, HttpServletRequest request) {

        if (StringUtils.isBlank(qrToken)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FAILED);
        }

        String redisQRToken = redis.get(SAAS_PLATFORM_LOGIN_TOKEN + ":" + qrToken);
        if (redisQRToken.equalsIgnoreCase(qrToken)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FAILED);
        }

        String headerAppUserId = request.getHeader("appUserId");
        String headerUserToken = request.getHeader("appUserToken");
        if (StringUtils.isBlank(headerAppUserId) || StringUtils.isBlank(headerUserToken)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FAILED);
        }
        // 对JWT进行校验
        String userJson = jwtUtils.checkJWT(headerUserToken.split("@")[1]);
        if (StringUtils.isBlank(userJson)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.HR_TICKET_INVALID);
        }

        // 执行后续正常业务
        // 生成预登录token
        String preToken = UUID.randomUUID().toString();
        redis.set(SAAS_PLATFORM_LOGIN_TOKEN + ":" + preToken, preToken, 5 * 60);
        redis.set(SAAS_PLATFORM_LOGIN_TOKEN_READ + ":" + preToken, "1," + preToken, 5 * 60);

        // 返回给手机端，app下次请求携带preToken
        return GraceJSONResult.ok(preToken);

    }

    /**
     * SAAS网页端每隔一段时间定时查询qrToken是否被读取，用于页面的展示标记
     *
     * @param qrToken
     * @return
     */
    @PostMapping("codeHasBeenRead")
    public GraceJSONResult codeHasBeenRead(String qrToken) {

        String readStr = redis.get(SAAS_PLATFORM_LOGIN_TOKEN_READ + ":" + qrToken);
        List list = new ArrayList();
        if (StringUtils.isNotBlank(readStr)) {
            String[] readArr = readStr.split(",");
            if (readArr.length >= 2) {
                list.add(Integer.valueOf(readArr[0]));
                list.add(readArr[1]);
            } else {
                list.add(0);
            }
        }
        return GraceJSONResult.ok(list);
    }

    @PostMapping("getQRLogin")
    public GraceJSONResult getQRLogin(String userId, String qrToken, String preToken) {
        String preTokenRedisArr = redis.get(SAAS_PLATFORM_LOGIN_TOKEN_READ + ":" + qrToken);
        if (StringUtils.isNotBlank(preTokenRedisArr)) {
            String preTokenRedis = preTokenRedisArr.split(",")[1];
            if (preTokenRedis.equalsIgnoreCase(preToken)) {
                // 根据用户id获得用户信息
                Users hrUser = usersService.getById(userId);
                if (hrUser == null) {
                    return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_NOT_EXIST_ERROR);
                }

                // 存入用户信息到redis中
                redis.set(REDIS_SAAS_USER_INFO + ":temp" + preToken, toJSon(hrUser), 5 * 60);
            }
        }
        return GraceJSONResult.ok();
    }

    @PostMapping("checkLogin")
    public GraceJSONResult checkLogin(String preToken) {
        if (StringUtils.isBlank(preToken)) {
            return GraceJSONResult.ok("");
        }

        String userJson = redis.get(REDIS_SAAS_USER_INFO + ":temp" + preToken);
        if (StringUtils.isBlank(userJson)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_NOT_EXIST_ERROR);
        }

        String saasUserToken = jwtUtils.createJWTWithPrefix(userJson, TOKEN_SAAS_PREFIX);
        redis.set(REDIS_SAAS_USER_INFO + ":" + saasUserToken, userJson);
        return GraceJSONResult.ok(saasUserToken);
    }

    @GetMapping("info")
    public GraceJSONResult info(String token) {
        String userJson = redis.get(REDIS_SAAS_USER_INFO + ":" + token);
        Users saasUser = new ObjectMapper().convertValue(userJson, Users.class);
        SaasUserVO saasUserVO = new SaasUserVO();
        BeanUtils.copyProperties(saasUser, saasUserVO);

        return GraceJSONResult.ok(saasUserVO);
    }

    @PostMapping("logout")
    public GraceJSONResult logout(String token) {
        return GraceJSONResult.ok();
    }

    private String toJSon(Object json) {
        try {
            return new ObjectMapper().writeValueAsString(json);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

}
